package org.vs.aop;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.vs.constant.RedisConstant;
import org.vs.domain.model.SysUser;
import org.vs.util.JwtUtil;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.utils.Convert;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigInteger;

@Component
@Aspect
@Slf4j
public class CheckBalanceAOP {
    @Resource
    private Credentials devCredentials;

    @Resource
    private Web3j web3j;

    @Resource
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(org.vs.annotation.CheckBalance)")
    public void pointcut() {
    }

    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) throws IOException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String authorization = request.getHeader("authorization");
        SysUser user = JwtUtil.getUser(authorization);

        Credentials credentials = JSON.parseObject(
                redisTemplate.opsForValue().get(RedisConstant.USER_REDIS_CREDENTIAL_KEY + user.getUserId()).toString(),
                Credentials.class);

        if (web3j.ethGetBalance(credentials.getAddress(), DefaultBlockParameterName.LATEST)
                .send().getBalance()
                .compareTo(Convert.toWei("10", Convert.Unit.WEI).toBigInteger()) <= 0) {
            transfer(credentials);
        }
    }

    private void transfer(Credentials credentials) throws IOException {
        Transaction transaction = Transaction.createEtherTransaction(
                devCredentials.getAddress(),
                null,
                BigInteger.valueOf(200000),
                BigInteger.valueOf(20000000),
                credentials.getAddress(),
                Convert.toWei("10", Convert.Unit.ETHER).toBigInteger());
        String hash = web3j.ethSendTransaction(transaction).send().getTransactionHash();
        log.info("转账 20 ETHER 交易 hash {} 被交易 账户 {}", hash, credentials.getAddress());
    }
}
